
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Expressions;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;

using System.Linq.Dynamic.Core;
 using Microsoft.EntityFrameworkCore; 
using DualControl.ControlMeasures.Dtos;
using Abp.Runtime.Session;
using Abp.Dapper.Repositories;
using DualControl.ControlMeasures.Authorization;
using DualControl.HazardSources;
using DualControl.RiskPoints;
using DualControl.Departments;

namespace DualControl.ControlMeasures
{
    /// <summary>
    /// ControlMeasure应用层服务的接口实现方法  
    ///</summary>

    [AbpAuthorize(ControlMeasureAppPermissions.ControlMeasure)]
    public class ControlMeasureAppService : DualControlAppServiceBase, IControlMeasureAppService
    {
        private readonly IRepository<ControlMeasure, int> _controlmeasureRepository;

        private readonly IRepository<HazardSource> _hazardsourceRepository;

        private readonly IRepository<RiskPoint> _riskpointrepository;
      
        private readonly IRepository<Department, long> _organizationUnitRepository;      

        private readonly IDapperRepository<ControlMeasure> _controlMeasuredapperRepository;



        /// <summary>
        /// 构造函数 
        ///</summary>
        public ControlMeasureAppService(
        IRepository<ControlMeasure, int> controlmeasureRepository,
        IRepository<HazardSource> hazardsourceRepository,
       IRepository<RiskPoint> riskpointrepository,
       IRepository<Department, long> organizationUnitRepository,
        IDapperRepository<ControlMeasure> controlMeasuredapperRepository
            )
        {
            _controlmeasureRepository = controlmeasureRepository;
            _hazardsourceRepository = hazardsourceRepository;
            _riskpointrepository = riskpointrepository;
            _organizationUnitRepository = organizationUnitRepository;
            _controlMeasuredapperRepository = controlMeasuredapperRepository;
        }

        /// <summary>
        /// 获取按照风险点排列的控制措施列表信息,包含风险点、风险源部分信息
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<HSControlMeasureListDto>> GetPagedHSControlMeasure(GetControlMeasuresInput input)
        {
           var query = from hs in _hazardsourceRepository.GetAll().Include("ControlMeasures")
                        join rp in _riskpointrepository.GetAll() on hs.RiskPointId equals rp.Id
                        select new HSControlMeasureListDto
                        {
                            Id = hs.Id,
                            //风险点
                            Code = rp.Code,
                            RiskPointId = rp.Id,
                            OrganizationUnitId = rp.OrganizationUnitId,                      RiskPointName = rp.Name,
                            HazardSourceName = hs.HazardSourceName,
                            RiskFactor = hs.RiskFactor,
                           ControlMeasures = hs.ControlMeasures
                        };


            var hazardsourceCount = await query.CountAsync();

            var hazardsources = await query
                    .OrderBy(input.Sorting).AsNoTracking()
                    .PageBy(input)
                    .ToListAsync();
           var hazardsourceListDtos = hazardsources.MapTo<List<HSControlMeasureListDto>>();
           return new PagedResultDto<HSControlMeasureListDto>(
                hazardsourceCount, hazardsourceListDtos
                );
        }


        /// <summary>
        /// 获取按照危险源排列的隐患排查信息列表,包含部门负责人姓名
        /// HTCriteriaListDto         
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<HTCriteriaListDto>> GetPagedHTCriteriaListDto(GetControlMeasuresInput input)
        {
            var query = from hs in _hazardsourceRepository.GetAll().Include("ControlMeasures")
                        join rp in _riskpointrepository.GetAll() on hs.RiskPointId equals rp.Id
                        join ou in _organizationUnitRepository.GetAll() on rp.OrganizationUnitId equals ou.Id                         
                        select new HTCriteriaListDto
                        { 
                            Id = hs.Id,                           
                            //风险点
                             Code = rp.Code,
                            RiskPointId = rp.Id,
                            OrganizationUnitId = rp.OrganizationUnitId,
                            //部门名称,在前端转换
                            RiskPointName = rp.Name,
                            HazardSourceName = hs.HazardSourceName,
                            RiskFactor = hs.RiskFactor,
                            RiskLevel = hs.RiskLevel.Value,
                            ControlMeasures = hs.ControlMeasures,
                            ResponsiblePerson = ou.User.Name
                        };


            var hazardsourceCount = await query.CountAsync();

            var hazardsources = await query
                    .OrderBy(input.Sorting).AsNoTracking()
                    .PageBy(input)
                    .ToListAsync();

            // var hazardsourceListDtos = ObjectMapper.Map<List <HazardSourceListDto>>(hazardsources);
            var hazardsourceListDtos = hazardsources.MapTo<List<HTCriteriaListDto>>();

            return new PagedResultDto<HTCriteriaListDto>(
                hazardsourceCount, hazardsourceListDtos
                );
        }


        /// <summary>
        /// 获取ControlMeasure的分页列表信息用Dapper实现
        /// 包含风险点名称、危险源名称等信息
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ControlMeasureListDto>> GetPagedControlMeasuresDapper(GetControlMeasuresInput input)
        {
            var tenantid = AbpSession.GetTenantId();
            var query = await _controlMeasuredapperRepository.QueryAsync<ControlMeasureListDto>("SELECT AbpUsers.id, AbpUsers.UserName,AbpUsers.Name ,Posts.Name as 'PostName' ,AbpOrganizationUnits.DisplayName as 'OrgName' from AbpUsers LEFT JOIN  UserPosts on AbpUsers.Id = UserPosts.UserId LEFT JOIN Posts on UserPosts.PostId = Posts.Id LEFT JOIN AbpUserOrganizationUnits on AbpUsers.Id = AbpUserOrganizationUnits.UserId LEFT JOIN AbpOrganizationUnits on AbpOrganizationUnits.id = AbpUserOrganizationUnits.OrganizationUnitId where AbpUsers.TenantId =" + tenantid);

            var sql = "";

            var controlMeasureListDto = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();

            return new PagedResultDto<ControlMeasureListDto>(
                 controlMeasureListDto.Count,
                 controlMeasureListDto
                );
        }



        /// <summary>
        /// 获取ControlMeasure的分页列表信息
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ControlMeasureListDto>> GetPagedControlMeasures(GetControlMeasuresInput input)
        {

            var query = _controlmeasureRepository.GetAll();
            // TODO:根据传入的参数添加过滤条件

            var controlmeasureCount = await query.CountAsync();

            var controlmeasures = await query
                    .OrderBy(input.Sorting).AsNoTracking()
                    .PageBy(input)
                    .ToListAsync();

            // var controlmeasureListDtos = ObjectMapper.Map<List <ControlMeasureListDto>>(controlmeasures);
            var controlmeasureListDtos = controlmeasures.MapTo<List<ControlMeasureListDto>>();

            return new PagedResultDto<ControlMeasureListDto>(
            controlmeasureCount, controlmeasureListDtos);
        }


        /// <summary>
        /// 通过指定id获取ControlMeasureListDto信息
        /// </summary>
        public async Task<ControlMeasureListDto> GetControlMeasureByIdAsync(EntityDto<int> input)
        {
            var entity = await _controlmeasureRepository.GetAsync(input.Id);

            return entity.MapTo<ControlMeasureListDto>();
        }

        /// <summary>
        /// MPA版本才会用到的方法
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<GetControlMeasureForEditOutput> GetControlMeasureForEdit(NullableIdDto<int> input)
        {
            var output = new GetControlMeasureForEditOutput();
            ControlMeasureEditDto controlmeasureEditDto;

            if (input.Id.HasValue)
            {
                var entity = await _controlmeasureRepository.GetAsync(input.Id.Value);

                controlmeasureEditDto = entity.MapTo<ControlMeasureEditDto>();

                //controlmeasureEditDto = ObjectMapper.Map<List <controlmeasureEditDto>>(entity);
            }
            else
            {
                controlmeasureEditDto = new ControlMeasureEditDto();
            }

            output.ControlMeasure = controlmeasureEditDto;
            return output;
        }

        //添加管控措施
        //一次可以添加4条 
        public async Task InsertControlMeasures(int RiskPointId, int HazardSourceId, string[] ControlMeasures)
        {
            var tenantid = AbpSession.GetTenantId();

            foreach (var controlstring in ControlMeasures)
            {
                if (controlstring.Length > 0)
                {
                    var controlMeasure = new ControlMeasure() { RiskPointId = RiskPointId, HazardSourceId = HazardSourceId, TenantId = tenantid, OrganizationUnitId = 1, ControlContent = controlstring };
                    await _controlMeasuredapperRepository.QueryAsync("insert into ControlMeasures (RiskPointId,HazardSourceId,OrganizationUnitId, TenantId,ControlContent) values (@RiskPointId,@HazardSourceId,@OrganizationUnitId,@TenantId,@ControlContent)", controlMeasure);
                }
            }

        }


        /// <summary>
        /// 添加或者修改ControlMeasure的公共方法
        /// 添加方法没有使用，现只使用更新的方法
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateOrUpdateControlMeasure(CreateOrUpdateControlMeasureInput input)
        {

            if (input.ControlMeasure.Id.HasValue)
            {
                await UpdateControlMeasureAsync(input.ControlMeasure);
            }
            else
            {
                await CreateControlMeasureAsync(input.ControlMeasure);
            }
        }


        /// <summary>
        /// 新增ControlMeasure，未使用
        /// </summary>

        protected virtual async Task<ControlMeasureEditDto> CreateControlMeasureAsync(ControlMeasureEditDto input)
        {
            //TODO:新增前的逻辑判断，是否允许新增

            var entity = ObjectMapper.Map<ControlMeasure>(input);

            entity = await _controlmeasureRepository.InsertAsync(entity);
            return entity.MapTo<ControlMeasureEditDto>();
        }

        /// <summary>
        /// 编辑ControlMeasure
        /// </summary>

        protected virtual async Task UpdateControlMeasureAsync(ControlMeasureEditDto input)
        {
            //TODO:更新前的逻辑判断，是否允许更新

            var entity = await _controlmeasureRepository.GetAsync(input.Id.Value);

            //原来的代码,在只编辑管控措施时，input只提供管控措施和记录Id，很多字段为空，映射后会使entity中的值为空
            //input.MapTo(entity);

            //编辑措施时
            if (input.ControlContent != null)
            {
                entity.ControlContent = input.ControlContent;
            }
            if (input.CheckCycle != null)
            {
                entity.CheckCycle = input.CheckCycle;
            }
            if (input.PostId != null)
            {
                entity.PostId = input.PostId;
            }
           

            // ObjectMapper.Map(input, entity);
            await _controlmeasureRepository.UpdateAsync(entity);
        }



        /// <summary>
        /// 删除ControlMeasure信息的方法
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>

        public async Task DeleteControlMeasure(EntityDto<int> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _controlmeasureRepository.DeleteAsync(input.Id);
        }



        /// <summary>
        /// 批量删除ControlMeasure的方法
        /// </summary>

        public async Task BatchDeleteControlMeasuresAsync(List<int> input)
        {
            //TODO:批量删除前的逻辑判断，是否允许删除
            await _controlmeasureRepository.DeleteAsync(s => input.Contains(s.Id));
        }


        /// <summary>
        /// 导出ControlMeasure为excel表,等待开发。
        /// </summary>
        /// <returns></returns>
        //public async Task<FileDto> GetControlMeasuresToExcel()
        //{
        //	var users = await UserManager.Users.ToListAsync();
        //	var userListDtos = ObjectMapper.Map<List<UserListDto>>(users);
        //	await FillRoleNames(userListDtos);
        //	return _userListExcelExporter.ExportToFile(userListDtos);
        //}



        //// custom codes

        //// custom codes end

    }
}

